﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Validity.Test.Constraints
{
  public class ConstraintTestBase<T>
  {
    private readonly IValidator<T> _validator;
    private readonly Int32 _rulesDefined;

    public ConstraintTestBase(IValidator<T> validator, Int32 rulesDefined)
    {
      Verify.NotNull(validator);

      _validator = validator;
      _rulesDefined = rulesDefined;
    }

    protected Boolean ValidateConstraintViolated(T value, String violationMessage)
    {
      IList<ValidationResult> results = _validator.Validate(value).ToList();

      Assert.AreEqual(_rulesDefined, results.Count);

      foreach (var result in results)
        VerifyInvalidResult(result, violationMessage);

      return true;
    }

    private void VerifyInvalidResult(ValidationResult result, String message)
    {
      Assert.IsFalse(result.IsValid);

      Assert.AreEqual(1, result.RuleViolations.Count()); 
      Assert.AreEqual(message, result.RuleViolations.First());
    }

    protected Boolean ValidateConstraintVerfied(T value)
    {
      IList<ValidationResult> results = _validator.Validate(value).ToList();

      Assert.AreEqual(_rulesDefined, results.Count);

      foreach (var result in results)
        VerifyValidResult(result);

      return true;
    }

    private void VerifyValidResult(ValidationResult result)
    {
      Assert.IsTrue(result.IsValid);
      Assert.AreEqual(0, result.RuleViolations.Count());
    }
  }
}
